#include <math.h>

#include "Equipement.h"
#include "Global.h"
#include "Affichage.h"


Equipement::Equipement(Affichage& oAffichage) : 
oAffichage(oAffichage), oBouclier(oAffichage) , oEpee(oAffichage), typeEquip(EQUIP_NONE),
posBouteilleMax(0)    , posBouteilleEquipee(0), typeArc(ARC_NONE), typeGant(GANT_NONE)  ,
QteMagie (32)         , QteMagieMax (32)      , QteFleches( 9)   , QteFlechesMax( 30)   ,
QteBombes(10)         , QteBombesMax(10)      , QteRubis  (50)   , QteRubisMax  (100)   ,
QteCles(4)
{
	imageEquipements = oAffichage.loadImage("data/images/link/objets.png", 0, 0, 255);

	for (int i = 0 ; i < MAX_EQUIPEMENT ; i++) tabEquipement[i] = false;
	for (int i = 0 ; i < MAX_BOUTEILLES ; i++) tabBouteille[i] = EQUIP_NONE;
}

TypeEquipement Equipement::getEquipActif() { return typeEquip; }
bool Equipement::aCetEquipement(TypeEquipement equip) { return tabEquipement[equip]; }

void Equipement::equiper( TypeEquipement equip, int IDBouteille )
{ setEquip(equip, IDBouteille); }

void Equipement::setBouteille( TypeEquipement bouteille )
{
	if ( posBouteilleMax == MAX_BOUTEILLES ) return;

	tabBouteille[posBouteilleMax++] = bouteille;
}

void Equipement::viderBouteille()
{ tabBouteille[posBouteilleEquipee] = typeEquip = EQUIP_BOUT_VIDE; }

void Equipement::trouverEquipement(TypeObjet type)
{ 
	TypeEquipement typeEquip;

	switch (type)
	{
			case OBJ_EPEE       : oEpee.setTypeEpee(EPEE_NORMAL)         ; break;
			case OBJ_EPEE_OR    : oEpee.setTypeEpee(EPEE_OR)             ; break;
			case OBJ_BOUC       : oBouclier.setTypeBouclier(BOUC_NORMAL) ; break;
			case OBJ_BOUC_OR    : oBouclier.setTypeBouclier(BOUC_OR)     ; break;

			case OBJ_POTI_ROUGE : setBouteille(EQUIP_POTI_ROUGE) ; break;
			case OBJ_POTI_VERTE : setBouteille(EQUIP_POTI_VERTE) ; break;
			case OBJ_POTI_BLEUE : setBouteille(EQUIP_POTI_BLEUE) ; break;
			case OBJ_BOUT_VIDE  : setBouteille(EQUIP_BOUT_VIDE ) ; break;

			case OBJ_GRAPPIN    : typeEquip = EQUIP_GRAPPIN    ; break;
			case OBJ_SAC_BOMBES : typeEquip = EQUIP_SAC_BOMBES ; break;
			case OBJ_BFEU       : typeEquip = EQUIP_BFEU       ; break;
			case OBJ_BGLACE     : typeEquip = EQUIP_BGLACE     ; break;
			case OBJ_LANTERNE   : typeEquip = EQUIP_LANTERNE   ; break;
			case OBJ_MARTEAU    : typeEquip = EQUIP_MARTEAU    ; break;
			case OBJ_PALMES     : typeEquip = EQUIP_PALMES     ; break;
			case OBJ_GANTS      : typeEquip = EQUIP_GANTS      ; typeGant = GANT_NORMAL ; break;
			case OBJ_GANTS_OR   : typeEquip = EQUIP_GANTS      ; typeGant = GANT_OR     ; break;
			case OBJ_ARC        : typeEquip = EQUIP_ARC        ; typeArc  = ARC_NORMAL  ; break;
			case OBJ_ARC_OR     : typeEquip = EQUIP_ARC        ; typeArc  = ARC_OR      ; break;

			default : break;
	}

	tabEquipement[typeEquip] = true;
	setEquip(typeEquip);
}

bool Equipement::setEquip( TypeEquipement type, int IDBouteille ) 
{ 
	if ( type == EQUIP_POTI_ROUGE || type == EQUIP_POTI_VERTE || 
		 type == EQUIP_POTI_BLEUE || type == EQUIP_BOUT_VIDE     )
	{
		if ( tabBouteille[IDBouteille] == type )
		{
			posBouteilleEquipee = IDBouteille;
			typeEquip = type;
			return true;
		}
	}
	else 
	{
		if (tabEquipement[type])
		{ typeEquip = type ; return true; }			
	}

	return false;
}

//          //
// Epee     //
//          //

TypeEpee Equipement::getTypeEpee()
{ return oEpee.getTypeEpee(); }

bool Equipement::setTypeEpee(TypeEpee type)
{ return oEpee.setTypeEpee(type); }

bool Equipement::hasEpee()
{ return oEpee.hasEpee(); }

//          //
// Bouclier //
//          //

TypeBouclier Equipement::getTypeBouclier()
{ return oBouclier.getTypeBouclier(); }

bool Equipement::setTypeBouclier(TypeBouclier type)
{ return oBouclier.setTypeBouclier(type); }

bool Equipement::hasBouclier()
{ return oBouclier.hasBouclier(); }

//          //
// Arc      //
//          //

TypeArc Equipement::getTypeArc()
{ return typeArc; }

bool Equipement::setTypeArc(TypeArc type)
{
	if (tabEquipement[EQUIP_ARC]) 
	{
		typeArc = type; 
		return true;
	}
	else
		return false;
}

//          //
// Gant     //
//          //

TypeGant Equipement::getTypeGant()
{ return typeGant; }

bool Equipement::setTypeGant(TypeGant type)
{
	if (tabEquipement[EQUIP_GANTS]) 
	{
		typeGant = type; 
		return true;
	}
	else
		return false;
}

//          //
// Magie    //
//          //
int Equipement::getQteMagieMax() { return QteMagieMax; }
void Equipement::setQteMagieMax(int val) { QteMagieMax = val; }
int Equipement::getQteMagie() { return QteMagie; }
void Equipement::ajusterQteMagie(int val) 
{ 
	QteMagie += val;

	if      ( QteMagie < 0           ) QteMagie = 0;
	else if ( QteMagie > QteMagieMax ) QteMagie = QteMagieMax;
}

//          //
// Fleches  //
//          //
TypeProjectile Equipement::getTypeFleche()
{
	return PROJ_FLECHE;
}

int Equipement::getQteFlechesMax() { return QteFlechesMax; }
void Equipement::setQteFlechesMax(int val) { QteFlechesMax = val; }
int Equipement::getQteFleches() { return QteFleches; }
void Equipement::ajusterQteFleches(int val) 
{ 
	QteFleches += val;

	if      ( QteFleches < 0           ) QteFleches = 0;
	else if ( QteFleches > QteFlechesMax ) QteFleches = QteFlechesMax;
}

//          //
// Bombes   //
//          //
int Equipement::getQteBombesMax() { return QteBombesMax; }
void Equipement::setQteBombesMax(int val) { QteBombesMax = val; }
int Equipement::getQteBombes() { return QteBombes; }
void Equipement::ajusterQteBombes(int val) 
{ 
	QteBombes += val;

	if      ( QteBombes < 0           ) QteBombes = 0;
	else if ( QteBombes > QteMagieMax ) QteBombes = QteBombesMax;
}

//          //
// Rubis    //
//          //
int Equipement::getQteRubisMax() { return QteRubisMax; }
void Equipement::setQteRubisMax(int val) { QteRubisMax = val; }
int Equipement::getQteRubis() { return QteRubis; }
void Equipement::ajusterQteRubis(int val) 
{ 
	QteRubis += val;

	if      ( QteRubis < 0           ) QteRubis = 0;
	else if ( QteRubis > QteMagieMax ) QteRubis = QteRubisMax;
}

//          //
// Cles     //
//          //
int Equipement::getQteCles() { return QteCles; }
void Equipement::ajusterQteCles(int val)
{ 
	QteCles += val;
	if ( QteCles < 0 ) QteCles = 0;
}

//          //
// Draw     //
//          //

void Equipement::drawEpee (int persoX, int persoY, TypeAnim anim, TypeDirection direction, int frame, int charge)
{ 	oEpee.draw(persoX, persoY, anim, direction, frame, charge); }

void Equipement::drawBouclier(int persoX, int persoY, TypeAnim anim, TypeDirection direction, int frame)
{ oBouclier.draw(persoX, persoY, anim, direction, frame); }

void Equipement::drawEquip(int persoX, int persoY, TypeDirection direction, int frame )
{
	int frameArc;
	SDL_Rect src;
	SDL_Rect dst;

	dst.x = persoX ; dst.y = persoY;

	getClip(src, direction, frame);

	switch (typeEquip)
	{
		case EQUIP_ARC :
			frameArc = (int) ceil((float)frame/2);
			switch (direction) 
			{
				case DIR_N : dst.x = dst.x -  2 - (3 * frameArc) ; dst.y = dst.y +  7 + (3 * frameArc); break;
				case DIR_S : dst.x = dst.x + 10 - (8 * frameArc) ; dst.y = dst.y + 10 + (5 * frameArc); break;
				case DIR_O : dst.x = dst.x -  1 - (2 * frameArc) ; dst.y = dst.y + 11 - (4 * frameArc); break;
				case DIR_E : dst.x = dst.x +  4 + (8 * frameArc) ; dst.y = dst.y + 11 - (4 * frameArc); break;
				default    : break;
			}
			break;	

		case EQUIP_GRAPPIN :
			switch (direction) 
			{
				case DIR_S : dst.x +=  6 ; dst.y += 17; break;
				case DIR_O : dst.x -=  7 ; dst.y += 14; break;
				case DIR_E : dst.x += 15 ; dst.y += 14; break;
				default    : break;
			}
			break;

		case EQUIP_BOUT_VIDE  :
		case EQUIP_POTI_ROUGE :
		case EQUIP_POTI_VERTE :
		case EQUIP_POTI_BLEUE :
			dst.x += 4; dst.y += 12;
			if (!frame) dst.y++;
			break;

		case EQUIP_BFEU    :
		case EQUIP_BGLACE  :
		case EQUIP_MARTEAU :
			switch (direction) 
			{
				case DIR_N : 
					dst.x -= 2 ; dst.y -= 5; 
					if      (frame == 1) dst.y += 3; 
					else if (frame == 2) dst.y += 7; 
					break;
				case DIR_S : 
					dst.x += 10 ; dst.y -= 3;
					if      (frame == 1) dst.y += 13; 
					else if (frame == 2) { dst.x-- ; dst.y += 23; }
					break;
				case DIR_O : 
					dst.y -= 1;
					if      (frame == 1) { dst.x -=  8 ; dst.y += 5 ; } 
					else if (frame == 2) { dst.x -= 10 ; dst.y += 15; } 
					break;
				case DIR_E : 
					dst.x += 8 ; dst.y -= 1;
					if      (frame == 1) { dst.x += 5 ; dst.y +=  5; } 
					else if (frame == 2) { dst.x += 4 ; dst.y += 15; } 
					break;
				default : break;
			}
			break;

		default: break;
	}
	
	oAffichage.applySurface(dst.x, dst.y, imageEquipements, &src);
}

void Equipement::getClip(SDL_Rect& src, TypeDirection direction, int frame)
{
	int frameArc;

	switch (typeEquip)
	{
		case EQUIP_ARC :
			frameArc = (int) ceil((float)frame/2);
			src.w = 16 ; src.h = 16;
			src.x = 16 * direction ; src.y = 16 * frameArc;
			break;
			
		case EQUIP_GRAPPIN :
			src.w = 8  ; src.h = 4; src.x = 56 ; src.y = 74;
			switch (direction) 
			{
				case DIR_N : break;
				case DIR_S : src.w  =  4 ; src.h = 8; break;
				case DIR_O : src.y +=  8 ;            break;
				case DIR_E : src.y += 12 ;            break;
			}

			break;

		case EQUIP_BOUT_VIDE  :
		case EQUIP_POTI_ROUGE :
		case EQUIP_POTI_VERTE  :
		case EQUIP_POTI_BLEUE :
			src.w = 8 ; src.h = 7; 
			src.x = 96 + 8 * frame ; src.y = 8 * getBouteille();
			if (src.x == 112) src.y = 0;
			if (src.y ==   0) src.x = 96;
			break;

		case EQUIP_BFEU :
			src.w = 14 ; src.h = 14;
			src.x = 14 * direction ; src.y = 32 + frame * 14;
			break;

		case EQUIP_BGLACE :
			src.w = 14 ; src.h = 14;
			src.x = 56 + (14 * direction) ; src.y = 32 + frame * 14;
			break;

		case EQUIP_MARTEAU :
			src.w = 14 ; src.h = 14;
			src.x = 14 * direction ; src.y = 42 + (32 + frame * 14);
			break;

		default : break;
	}
}

int Equipement::getBouteille()
{
	switch (typeEquip)
	{
		case EQUIP_BOUT_VIDE  : return 0;
		case EQUIP_POTI_ROUGE : return 1;
		case EQUIP_POTI_VERTE : return 2;
		case EQUIP_POTI_BLEUE : return 3;
		default : return -1;
	}
}

Equipement::~Equipement() 
{ SDL_FreeSurface(imageEquipements); }
